<template>
  <div>
    <el-form :model="boardBaseModel" class="affix-form" inline labelPosition="center">
      <sticky :class-name="'sub-navbar'" :z-index="2000">

        <!--        <el-button @click="()=>verticalMediate(gridList)" size="mini" type="primary">vt</el-button>-->
        <!--        <el-button @click="()=>horizonMediate(gridList)" size="mini" type="primary">hz</el-button>-->
        <!--        <el-button @click="()=>allMediate(gridList)" size="mini" type="primary">am</el-button>-->

        <span class="base-info-azure">
            <el-tag style="margin-right: 10px;" type="success">{{currentClothSize}}</el-tag>
            <el-tag style="margin-right: 20px;">{{realClothSize}}</el-tag>
        </span>

        <!--        <el-switch-->
        <!--          active-text="自由拼版"-->
        <!--          inactive-text="普通拼版"-->
        <!--          style="margin-right: 35px"-->
        <!--          v-model="">-->
        <!--        </el-switch>-->
        <!--                :disabled="gridListHasSomeBarcode"    -->
        <el-form-item label="选择画布" prop="MaterialItemId" size="mini">
          <material-select-query
            :mid.sync="boardBaseModel.MaterialItemId"
            @material-change="mdSelectChange"/>
        </el-form-item>

        <el-button
          :disabled="!hasSelectPaintCloth"
          @click="paintClothInfoDrawer=true"
          round size="mini" style="margin-right: 20px;"
          type="primary">画布详情信息
        </el-button>

        <el-form-item label="利用率">
          <el-progress :color="customColors"
                       :percentage="UsefulRate"
                       :stroke-width="25"
                       style="width: 150px;"
                       text-inside/>
        </el-form-item>

        <el-button @click="sync2Server" icon="el-icon-refresh" round size="mini" type="success">保存</el-button>

      </sticky>
    </el-form>


    <div style="display: flex;margin: 10px;height: 507px;">
      <el-card>
        <FullMoon
          :active-key.sync="activeKey"
          :browserH="browserH"
          :browserW="browserW"
          :cus-paint-cloth-style="boardBarcodeStyle"
          :data-list.sync="gridList"
          :gridStyleFn="gridStyleFn"
          :key="clothKey"
          :paint-cloth="realClothWH"
          :userConfig="userConfig"
          ref="full"
        >

          <template #otherContextMenu="{contextMenuStore:{grid,idx}}">
            <v-contextmenu-item divider></v-contextmenu-item>
            <v-contextmenu-group max-width="240px" style="font-size: 18px;">

              <!--                    //  verticalMediate | horizonMediate | allMediate-->
              <el-tooltip :open-delay="1000" content="垂直居中" effect="dark" style="z-index: 999">
                <v-contextmenu-item @click="()=>moveGrid({needHandle:grid,pos:'verticalMediate'})">
                  <i class="el-icon-d-caret"></i>
                </v-contextmenu-item>
              </el-tooltip>

              <el-tooltip :open-delay="1000" content="水平居中" effect="dark" style="z-index: 999">
                <v-contextmenu-item @click="()=>moveGrid({needHandle:grid,pos:'horizonMediate'})">
                  <i class="el-icon-back"></i>
                  <i class="el-icon-right"></i>
                </v-contextmenu-item>
              </el-tooltip>

              <el-tooltip :open-delay="1000" content="(垂直+水平)居中" effect="dark" style="z-index: 999">
                <v-contextmenu-item @click="()=>moveGrid({needHandle:grid})">
                  <i class="el-icon-s-grid"></i>
                </v-contextmenu-item>
              </el-tooltip>

              <el-tooltip :open-delay="1000" content="删除" effect="dark" style="z-index: 999">
                <v-contextmenu-item @click="()=>deleteGridByKey({gridList,grid,idx})">
                  <i class="el-icon-delete"></i>
                </v-contextmenu-item>
              </el-tooltip>
            </v-contextmenu-group>
            <v-contextmenu-item>
              {{`tip:按住ctrl+鼠标左键多选`}}
            </v-contextmenu-item>
          </template>
          <template #default="{data:{grid, idx,gridList}}">
            <div style="width: 100%;height:100%;position:relative">

              <!--
              style="position: absolute;
                  left: 20px;
                  top: 20px;
                  width: 10px;
                  border-radius: 50%;
                  background: rgb(0, 0, 0);
                  height: 10px;"
              -->
              <!--              <div  v-if=""></div>-->
              <div :style="generateBarcodePosStyle({grid,barcodePos:grid.barcodePos})"></div>
            </div>
          </template>
        </FullMoon>
      </el-card>

      <el-card :body-style="{height:'100%'}" style="flex: 1;margin-left: 10px;">
        <template v-if="!hasSelectPaintCloth">
          <div style="height:100%;display: flex;align-items: center;justify-content: center">
            <h3>请选择画布</h3>
          </div>
        </template>

        <!--        <template v-else-if="isFreeTemplateMode">-->
        <!--          <div slot="header">-->
        <!--            <span>自由拼版</span>-->
        <!--          </div>-->
        <!--          <div style="display: flex;justify-content: center;align-items: center">-->
        <!--            <el-form :label-width="globalLabelWidth" :model="boardBaseModel" size="mini">-->
        <!--              <el-row :gutter="globalGutter">-->
        <!--                <el-col :key="e.prop" v-bind="{xl: 12,lg: 12,md: 24,sm: 24,xs: 24}"-->
        <!--                        v-for="e in [-->
        <!--                          {label:'最大宽',prop:'Width',isDisabled:true},-->
        <!--                          {label:'最大高',prop:'Height',isDisabled:true},-->
        <!--                          {label:'最小宽',prop:'MinWidth',isDisabled:false},-->
        <!--                          {label:'最小高',prop:'MinHeight',isDisabled:false},-->
        <!--                        ]">-->
        <!--                  <el-form-item :label="e.label" :prop="e.prop">-->
        <!--                    <el-input-number :disabled="e.isDisabled" controls-position="right"-->
        <!--                                     v-model="boardBaseModel[e.prop]"/>-->
        <!--                  </el-form-item>-->
        <!--                </el-col>-->
        <!--              </el-row>-->
        <!--            </el-form>-->

        <!--          </div>-->
        <!--        </template>-->

        <template v-else>
          <div slot="header" style="display: flex;flex-direction: column">

            <div>
              <el-tag>{{`当前拼版模式 : ${isFreeTemplateMode?'自由拼版':'普通'}`}}</el-tag>

              <el-popover
                content="清空画布上的全部模板可以切换为自由拼版模式⚛⛏🐉"
                placement="bottom"
                title="提示(tip)"
                trigger="click"
                width="200">
                <i class="el-icon-question" slot="reference"></i>
              </el-popover>

              <span style="margin-left: 20px">
              <el-button @click="addGridItem" icon="el-icon-circle-plus" size="mini" type="success">新增</el-button>
              <el-popconfirm
                @onConfirm="clearGridList"
                title="您确定要清空当前所有的模板？">
                <el-button icon="el-icon-error" size="mini" slot="reference" type="info">清空</el-button>
              </el-popconfirm>
               <el-popover
                 placement="bottom"
                 title="个人设置"
                 trigger="click"
                 width="350">
                  <el-button
                    circle
                    icon="el-icon-s-tools"
                    size="mini" slot="reference" type="primary">
                  </el-button>

               <el-form :label-width="globalLabelWidth" :model="userConfig" size="mini">
                                   <el-form-item label="吸附强度" prop="snapSpace">
                 <el-slider
                   :max="15"
                   v-model="userConfig.snapSpace"/>
                               </el-form-item>
                         </el-form>
            </el-popover>

            </span>
            </div>
          </div>
          <el-table
            :data="gridList"
            :row-class-name="tableRowClassName"
            @row-click="handleRowClick" max-height="400" row-key="key">

            <el-table-column
              label="颜色"
              prop="bc"
              width="70"
            >
              <template #default="{row}">
                <el-color-picker size="mini" v-model="row.bc"/>
              </template>
            </el-table-column>

            <el-table-column
              :label="e.label"
              :prop="e.key"
              v-for="e in  [
                { key: 'x', label: 'x轴坐标' },
                { key: 'y', label: 'y轴坐标' },
                { key: 'w', label: '宽(mm)', },
                { key: 'h', label: '高(mm)', },
                ]"
              width="160">
              <template v-slot="{row}">
                <el-input-number
                  :min="getMinWH({prop:e.key,row})"
                  @change="repaint" size="mini" v-model="row[e.key]"/>
              </template>
            </el-table-column>

            <el-table-column
              :formatter="(row, column, cellValue, index)=>`${cellValue}°`"
              label="角度"
              prop="rotateAngle"
              width="70">
            </el-table-column>

            <!--                 v-if="!boardBaseModel.RemarkDirection"               -->
            <el-table-column
              label="相对照片位置"
              prop="barcodePos"
              width="160"
            >
              <template #default="{row}">
                <!--         v-model="row['barcodePos']"     -->
                <ASelect
                  :options="barcodeDirectionOptions"
                         :clearable="false"
                         :value="row['barcodePos']"
                         @change="newV => handleTemplateBarcodeChange({row,newV,oldV:row['barcodePos']})"
                         size="mini"/>
              </template>
            </el-table-column>

            <el-table-column
              align="center"
              label="最后条码位置"
              prop="barcodePos"
              width="120"
            >
              <template #default="{row}">
                <el-tag>
                  {{getLastBarcodePosTextShow(row['rotateAngle'],row['barcodePos'])}}
                </el-tag>
              </template>
            </el-table-column>

            <!--          <el-table-column-->
            <!--            label="旋转角度"-->
            <!--            prop="rotateAngle"-->
            <!--            width="160"-->
            <!--          >-->
            <!--            <template #default="{row}">-->
            <!--              <a-select :options="rotateAngleList"-->
            <!--                        :value="row.rotateAngle"-->
            <!--                        @change="newV => handleRotateAngleChange({newV,oldV:row.rotateAngle,row})"/>-->
            <!--            </template>-->
            <!--          </el-table-column>-->

            <el-table-column
              fixed="right"
              label="操作"
              width="100">
              <template v-slot="{row,$index}">
                <el-button
                  @click.native.prevent="_ => rightRotateGrid({row})"
                  circle icon="el-icon-refresh-right" size="mini"
                  type="primary">
                </el-button>

                <el-button
                  @click.native.prevent="deleteGrid({$index,gridList,row})"
                  circle icon="el-icon-delete" plain
                  size="mini" type="primary">
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </template>
      </el-card>
    </div>

    <!--  全局模板条码信息配置  -->
    <el-card style="margin: 10px;" v-if="!isFreeTemplateMode">
      <div slot="header">
        <span>模板条码信息</span>
      </div>

      <el-form :label-width="globalLabelWidth" :model="gridBarcodeConfig" size="mini" v-if="!isFreeTemplateMode">
        <el-row :gutter="globalGutter">
          <el-col :key="e.prop" v-bind="global6Grid" v-for="e in [
                  {label:'条码高',prop:'bh'},
                  {label:'条码大小',prop:'bSize'},
                  {label:'条码字体大小',prop:'bfSize'}
                  ]">
            <el-form-item :label="e.label" :prop="e.prop">
              <el-input-number @change="newV => handleGridBcChange({newV,gridList,prop:e.prop})"
                               controls-position="right"
                               v-model="gridBarcodeConfig[e.prop]"/>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>

    </el-card>


    <!-- title="画布资料信息"  -->
    <el-drawer
      :visible.sync="paintClothInfoDrawer"
      :with-header="false"
      size="50%"
      z-index="999999">

      <div style="height: 100vh;overflow-y: scroll">
        <el-card style="margin: 10px;">
          <div slot="header">
            <el-tag type="primary">基本信息</el-tag>
          </div>
          <el-form :label-width="globalLabelWidth" :model="boardBaseModel" size="mini">
            <el-row :gutter="globalGutter">


              <!--            <el-col v-bind="globalGrid2">-->
              <!--              <el-form-item label="请选择画布" prop="MaterialItemId" size="mini">-->
              <!--                <material-select-query-->
              <!--                  :mid.sync="boardBaseModel.MaterialItemId"-->
              <!--                  @material-change="mdSelectChange"/>-->
              <!--              </el-form-item>-->
              <!--            </el-col>-->

              <el-col v-bind="globalGrid2">
                <el-form-item label="模板名字" prop="Name">
                  <el-input v-model="boardBaseModel.Name"/>
                </el-form-item>
              </el-col>

              <el-col v-bind="globalGrid2">
                <el-form-item label="打印类型" prop="ProductPrintTypeId">
                  <product-print-type v-model="boardBaseModel.ProductPrintTypeId"/>
                </el-form-item>
              </el-col>

              <el-col>
                <el-form-item label="打印文件夹" prop="PrinterFolder">
                  <el-input v-model="boardBaseModel.PrinterFolder"/>
                </el-form-item>
              </el-col>

              <!--              <el-col>-->
              <!--                <el-form-item label="拼版类型">-->
              <!--                  <el-switch-->
              <!--                    active-text="自由"-->
              <!--                    inactive-text="普通"-->
              <!--                    style="margin-right: 35px"-->
              <!--                    v-model="isFreeTemplateMode">-->
              <!--                  </el-switch>-->
              <!--                </el-form-item>-->
              <!--              </el-col>-->

              <el-col>
                <el-form-item label="备注信息" prop="Reamrk">
                  <el-input
                    :autosize="{ minRows: 2, maxRows: 5}"
                    type="textarea"
                    v-model="boardBaseModel.Reamrk">
                  </el-input>
                </el-form-item>
              </el-col>

            </el-row>
          </el-form>
        </el-card>

        <el-card style="margin: 10px;">
          <div slot="header">
            <el-tag type="info">画布条码信息</el-tag>
          </div>

          <el-form :label-width="globalLabelWidth" :model="boardBaseModel" size="mini">
            <el-row :gutter="globalGutter">

              <el-col v-bind="globalGrid2">
                <el-form-item label="画布条码方向" prop="RemarkDirection">
                  <!-- @change="newV => handleBarcodeChange({row,newV,oldV:row['barcodePos']})" size="mini" -->
                  <!--                 -->
                  <ASelect
                    :options="barcodeDirectionOptions"
                    @change="handleBoardCodeChange"
                    v-bind="getValue({obj:boardBaseModel,prop:'RemarkDirection'})"
                  />
                </el-form-item>
              </el-col>
              <el-col :key="e.prop" v-bind="globalGrid2" v-for="e in [
              {label:'画布条码高(mm)',prop:'RemarkHeight'},
              {label:'画布条码大小',prop:'RemarkCodeSize'},
              {label:'画布条码字体大小',prop:'RemarkFontSize'}
              ]">
                <el-form-item :label="e.label" :prop="e.prop">
                  <el-input-number
                    v-bind="getValue({obj:boardBaseModel,prop:[e.prop]})"
                    v-on="getChange({obj:boardBaseModel,prop:[e.prop]})"
                  />
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
        </el-card>

        <el-card style="margin: 10px;">
          <div slot="header">
            <el-tag type="success">自由拼版设置</el-tag>
          </div>
          <el-form :label-width="globalLabelWidth" :model="boardBaseModel" size="mini">
            <el-row :gutter="globalGutter">
              <!--              <template>-->
              <!--                &lt;!&ndash;      普通拼版  直接取材料的宽高    &ndash;&gt;-->
              <!--              </template>-->
              <!--              v-if="isFreeTemplateMode"     -->
              <template>
                <!--     自由拼版     -->
                <el-col :key="e.prop" v-bind="globalGrid2" v-for="e in [
              {label:'最大宽',prop:'Width' ,      max:originCloth.w, min:boardBaseModel['MinWidth']}, //  ,isDisabled:true
              {label:'最大高',prop:'Height',      max:originCloth.h, min:boardBaseModel['MinHeight']}, //  ,isDisabled:true
              {label:'最小宽',prop:'MinWidth',    max:boardBaseModel['Width'],min:0,isDisabled:!isFreeTemplateMode},
              {label:'最小高',prop:'MinHeight',   max:boardBaseModel['Height'],min:0,isDisabled:!isFreeTemplateMode},
              ]">
                  <el-form-item :label="e.label" :prop="e.prop">
                    <el-input-number
                      :disabled="!!e.isDisabled"
                      :max="e.max" :min="e.min"
                      @change="onMaxWHChange" v-model="boardBaseModel[e.prop]"/>
                  </el-form-item>
                </el-col>
              </template>
            </el-row>
          </el-form>
        </el-card>

      </div>

    </el-drawer>
  </div>

</template>

<script>
  import FullMoon from '@/views/makeupTemplate/c/full-moon/FullMoon'
  import AzureDynamicTable from '@/components/ATheFridayClub/mDynamicTable/AzureDynamicTable'
  import AInlineEdit from '@/components/ATheFridayClub/inlineEdit/AInlineEdit'
  import AzureLineSelect from '@/components/ATheFridayClub/businessSelect/line/azureLineSelect'
  import ASelect from '@/components/ATheFridayClub/ASelect'
  import Sticky from '@/components/Sticky/index'
  import layoutMixin from '@/mixins/layoutMixin'
  import form from '@/mixins/form'
  import ProductPrintType from '@/components/ATheFridayClub/businessSelect/print/productPrintType'
  import { customColors } from '@/utils/fridayClub/color'
  import MaterialSelectQuery from '@/views/makeupTemplate/MaterialSelectQuery'
  import {
    allMediate,
    autoHandleArr,
    barcodeDirectionOptions, directionEngChineseEnum, directionEnum,
    // directionEnum,
    generateBarcodePosStyle,
    GridItemPO,
    GridItemVO, horizonMediate, lastBarCodePos, Rectangle,
    rotateAngleList, verticalMediate
  } from '@/views/makeupTemplate/boardTemplateUtil'
  import { GetBoardModel, ModifyBoardModelAndDetail } from '@/api/template'
  import { ERR_OK } from '@/utils/commons'

  const getUnicornKey = ({ prop = 'key' } = {}) => (list) => {
    let uid = 0
    const keys = list.map(v => v[prop])
    // console.log(list)
    while (keys.includes(uid)) {
      uid++
    }
    return uid
  }

  const getBrowserH = (rw, rh, bw) => {
    return bw * rh / rw
  }

  //  unit mm
  const noop = function() {
  }

  const noneTransfer = (v) => !!v ? v : 'none'

  const free_prefix = 'FreeDetail'

  export default {
    name: 'modifyMakeupTemplate',
    data() {
      // this.ctrling = false
      return {
        ctrling: false,
        free_prefix,
        customColors,
        userConfig: {
          snapSpace: 5
        },
        //  全局的grid条码配置
        gridBarcodeConfig: {
          // RemarkHeight: 6,
          // RemarkCodeSize: 20,
          // RemarkFontSize: 20
          bh: 3,
          bSize: 20,
          bfSize: 20
        },

        boardBaseModel: {
          'WindowDirection': 0,
          'IsTransverse': false,
          'Status': 1,
          'BoardModelID': 0,

          Name: '',
          Reamrk: '',
          PrinterFolder: '',
          ProductPrintTypeId: '',
          UsefulRate: 0,

          //  最大宽高 (画布大小)
          MaterialItemId: '',
          'Width': 0,
          'Height': 0,
          // MaxWidth: 0,
          // MaxHeight: 0,

          //  自由拼版用
          'MinWidth': 0,
          'MinHeight': 0,

          // 普通板块的条码信息
          'RemarkHeight': 0,
          'RemarkDirection': '',
          'RemarkCodeSize': 0,
          'RemarkFontSize': 0,

          //  自由拼版的条码信息放这里
          [`${free_prefix}RemarkHeight`]: 0,
          [`${free_prefix}RemarkDirection`]: '',
          [`${free_prefix}RemarkCodeSize`]: 0,
          [`${free_prefix}RemarkFontSize`]: 0
        },

        activeKey: -1,
        gridList: [],

        multiSelectGridIds: [],

        browserW: 600,
        browserH: 400,
        clothKey: 0,
        barcodeDirectionOptions,
        rotateAngleList,

        paintClothInfoDrawer: false,

        backGridList: [],
        originCloth: { w: 0, h: 0 }

      }
    },
    created() {
      // const { $route } = this.$route
      const { BoardModelID } = this.$route.query
      if (BoardModelID) {
        this.getGridItemList({ BoardModelID })
      }

    },
    async mounted() {
      this.listenCtrlCombineClick()
    },
    mixins: [layoutMixin, form],
    computed: {
      getLastBarcodePosTextShow() {
        return (rotateAngle, barcodePos) => {
          // console.log('......................')
          // console.log(rotateAngle, barcodePos)
          barcodePos = !!barcodePos ? barcodePos : directionEnum.none
          return directionEngChineseEnum [lastBarCodePos[directionEnum[barcodePos]][rotateAngle]]
        }
      },
      //  get id by key
      multiSelectGrids() {
        const getListByKeys = (keys, list) => {
          return list.filter(g => keys.includes(g.key))
        }
        return getListByKeys(this.multiSelectGridIds, this.gridList)
      },

      currentClothSize() {
        const { Width, Height } = this.boardBaseModel
        if (!this.hasSelectPaintCloth) {
          return '请选择画布'
        }
        return `当前画布大小 : ${Width} * ${Height} (mm)`
      },
      realClothSize() {
        let cloth = this.realClothWH
        // const { MaxHeight, MaxWidth } = this.boardBaseModel
        // if (this.isFreeTemplateMode) {
        //   cloth = { w: MaxWidth, h: MaxHeight }
        // }
        if (!this.hasSelectPaintCloth) {
          return '请选择画布'
        }
        console.log('realClothSize >>>>>>>>>>>>>>>> %o', cloth)
        return `实际可用${cloth.w} * ${cloth.h} mm`
      },
      hasSelectPaintCloth() {
        const mid = this.boardBaseModel?.MaterialItemId
        const r = mid >= 0 && mid !== ''
        console.log(r)
        return r
      },
      isFreeTemplateMode: {
        get() {
          // const { BoardModelID } = this.$route.query
          const isFreeTemplate = (gridList) => {
            const hasGrid = gridList?.length > 0
            // console.log('hasGrid', hasGrid)
            return !hasGrid
          }
          return isFreeTemplate(this.gridList)
        }
        // set(newV) {
        //   console.log(' setter ~~~~~~~~~~~~', newV)
        //   //  true free    false  normal
        //   if (newV) {
        //     this.backGridList = this.gridList
        //     this.gridList = [
        //       // new GridItem({
        //       //   w: 1, h: 1
        //       // })
        //     ]
        //   } else {
        //     this.gridList = this.backGridList
        //   }
        //   this.repaint()
        // }
      },
      gridListHasSomeBarcode() {
        return this.gridList.some(v => v.barcodePos)
      },
      boardBarcodeStyle() {
        const { RemarkDirection } = this.boardBaseModel
        return RemarkDirection ? {
          [`border-${RemarkDirection}`]: '12px solid deepskyblue'
        } : {}
      },
      realClothWH() {
        let {
          Width: w, Height: h,
          RemarkHeight, RemarkDirection,
          [`${free_prefix}RemarkHeight`]: frh, [`${free_prefix}RemarkDirection`]: frr
        } = this.boardBaseModel

        RemarkHeight = this.isFreeTemplateMode ? frh : RemarkHeight
        RemarkDirection = this.isFreeTemplateMode ? frr : RemarkDirection
        const base = { w, h }
        const conditions = {
          top: { h: h - RemarkHeight },
          left: { w: w - RemarkHeight },
          right: { w: w - RemarkHeight },
          bottom: { h: h - RemarkHeight },
          none: { w, h }
        }
        return Object.assign({}, base, conditions[RemarkDirection |> noneTransfer])
      },
      UsefulRate() {
        const calcAreaUseful = (cw, ch, list) => {
          const clothArea = (cw * ch)
          if (clothArea === 0) {
            return 0
          }
          const gridTotalArea = list.reduce((acc, cur) => {
            const [w, h] = cur
            return acc + (w * h)
          }, 0)

          return gridTotalArea / clothArea * 100 |> Math.floor
        }
        const { Height, Width } = this.boardBaseModel

        //  需要减去条码面积
        return calcAreaUseful(Width, Height, this.gridList.map(v => [v.w, v.h]))
      }
    },
    methods: {
      listenCtrlCombineClick() {
        const fn = e => {
          if (e.ctrlKey) {
            console.log(e)
            if (e?.target?.parentNode?.__vue__) {
              const v = e.target.parentNode.__vue__
              const m = this.multiSelectGridIds
              if (!m.includes(v.uid)) {
                m.push(v.uid)
              } else {
                m.splice(m.indexOf(v.uid), 1)
              }
            }
          }
        }
        window.addEventListener('click', fn)
        this.$once('hook:beforeDestroy', () => window.removeEventListener('click', fn))
      },
      //  verticalMediate | horizonMediate | allMediate
      moveGrid({ needHandle = [], pos = 'allMediate' } = {}) {
        const removeFns = {
          verticalMediate, horizonMediate, allMediate
        }
        // if (!needHandle || needHandle.length === 0) {
        //   needHandle = this.getListByKeys()
        // }
        const set = (nh) => {
          this.gridList = removeFns[pos](this.gridList, nh, this.realClothWH)
          this.repaint()
        }
        if (this.multiSelectGrids && this.multiSelectGrids.length > 0) {
          set(this.multiSelectGrids)
          this.multiSelectGridIds = []
        } else {
          set(needHandle)
        }
      },
      handleGridBcChange({ newV, gridList, prop }) {
        autoHandleArr(gridList, (item) => item[prop] = newV)
      },
      onMaxWHChange() {
        this.repaint()
      },
      handleBoardCodeChange(v) {
        // this.repaint() //  多个change会被合并
        // value: obj[this.isFreeTemplateMode ? this.free_prefix + prop : prop]
        console.log('cccccc')
        const prefix = this.isFreeTemplateMode ? this.free_prefix : ''

        const ov = this.boardBaseModel[prefix + 'RemarkDirection']
        console.log(' v ov ~~~~~~~~~~~', v, ov)

        const setV = (dv, prop) => {
          if (v && !ov) {
            return dv
          } else if (!v && ov) {
            return 0
          }
          return this.boardBaseModel[prefix + prop]
        }
        //  需要改进,这里太挫了
        //  把其他的值给改掉
        this.boardBaseModel = {
          ...this.boardBaseModel,
          [`${prefix}RemarkHeight`]: setV(6, 'RemarkHeight'),
          [`${prefix}RemarkCodeSize`]: setV(20, 'RemarkCodeSize'),
          [`${prefix}RemarkFontSize`]: setV(20, 'RemarkFontSize')
        }
        this.getChange({ obj: this.boardBaseModel, prop: 'RemarkDirection' }).change(v)
      },
      getValue({ obj, prop } = {}) {
        return {
          value: obj[this.isFreeTemplateMode ? this.free_prefix + prop : prop]
        }
      },
      getChange({ obj, prop } = {}) {
        return {
          change: (newV) => {
            obj[this.isFreeTemplateMode ? this.free_prefix + prop : prop] = newV
            this.repaint()  //
          }
        }
      },
      sync2Server() {
        this.saveTemplateInfo()
      },
      async saveTemplateInfo() {
        // console.log(JSON.stringify(this.boardBaseModel))
        const { bSize, bfSize, bh } = this.gridBarcodeConfig
        const transformVO2PO = (vo) => autoHandleArr(vo, (item) => new GridItemPO({
          ...item, bSize, bfSize, bh
        }))
        // this.$notify.info({ title: '正在开发,请不要打扰我⚛⛏⚒🧱🗝🔧' })
        // this.gridList |>  transformVO2PO |> JSON.stringify |> console.log
        const { UsefulRate } = this
        //  call api
        const { Code } = await ModifyBoardModelAndDetail({
            ...this.boardBaseModel,
            // ...(() => {
            //   const base = { ...this.boardBaseModel }
            //   if (this.isFreeTemplateMode) {
            //     const { MaxWidth, MaxHeight } = this.boardBaseModel
            //     Object.assign(base, {
            //       Width: MaxWidth,
            //       Height: MaxHeight
            //     })
            //   }
            //   return base
            // })(),
            UsefulRate,
            BoardModelDetails: this.gridList |>  transformVO2PO
          }
        )
        if (+Code === ERR_OK) {
          this.$notify.success({ title: '添加模板成功!' })
          this.$router.back()
        }
      },
      mdSelectChange({ w, h } = {}) {

        console.log('mdSelectChange ~~~~~~')

        this.setRealCloth(w, h)
        this.setOriginCloth(w, h)
        // this.setMaxWH(w, h)
      },
      setOriginCloth(w, h) {
        console.log('set origin ', w, h)

        this.originCloth = { w, h }
      },
      // setMaxWH(MaxWidth, MaxHeight) {
      //   this.boardBaseModel = { ...this.boardBaseModel, MaxWidth, MaxHeight }
      // },
      //  下拉框旋转角度 todo
      handleRotateAngleChange({ row, newV, oldV }) {
        const conditions = {
          0: {
            90: {},
            180: noop,
            270: {}
          },
          90: {
            0: {},
            180: {},
            270: {}
          },
          180: {
            0: noop,
            90: {},
            270: {}
          },
          270: {
            0: {},
            90: {},
            180: {}
          }
        }
        // conditions[oldV][newV]()
      },
      //  mm
      setRealCloth(w, h) {
        this.boardBaseModel.Width = w
        this.boardBaseModel.Height = h  //  注意,computed中的拦截修改是同步的
        this.repaint()
      }
      ,
      handleRowClick(row) {
        // console.log(row)
        this.activeKey = row.key
      }
      ,
      tableRowClassName({ row, rowIndex }) {
        if (row.key === this.activeKey) {
          return 'azure-select-row'
        }
        return ''
      },
      // getMax
      getMinWH({ prop, row }) {
        const { bh } = this.gridBarcodeConfig
        // const { w, h } = this.realClothWH
        const condition = {
          x: 0,
          y: 0,
          w: bh,
          h: bh
        }
        return condition[prop]
      },
      handlePaintClothSizeChange() {

      },
      _addWh({ grid, newV, oldV, barcodeHeight, setWProp = 'w', setHProp = 'h' }) {
        const _getAddFn = () => {

          const addWHFn = (grid => ({ w = setWProp, h = setHProp, wSpan = 0, hSpan = 0 } = {}) => () => {
            grid[w] += wSpan
            grid[h] += hSpan

            console.log('add fn')

            console.log(wSpan, hSpan)
            console.log(grid)

          })(grid)

          const s = barcodeHeight
          const _oldVPos = noneTransfer(oldV)
          const _newVPos = noneTransfer(newV)

          const removeHAddW = addWHFn({ wSpan: s, hSpan: -s })
          const removeWAddH = addWHFn({ wSpan: -s, hSpan: s })
          //  old -> new
          const conditions = {
            top: {
              top: noop, //  anything has not change
              right: removeHAddW, //  h-s,w+s
              bottom: noop,  // do not need change
              left: removeHAddW, //  h-s,w+s
              none: addWHFn({ hSpan: -s })   //  h-s
            },
            right: {
              top: removeWAddH, //  h+s,w-s
              right: noop, //  anything has not change
              bottom: removeWAddH,  //  h+s,w-s
              left: noop,   // do not need change
              none: addWHFn({ wSpan: -s })  //  w-s
            },
            bottom: {
              top: noop, // do not need change
              right: removeHAddW,   //  h-s,w+s
              bottom: noop,   //  anything has not change
              left: removeHAddW, //  h-s,w+s
              none: addWHFn({ hSpan: -s })  //  h-s
            },
            left: {
              top: removeWAddH,  //  h+s,w-s
              right: noop, // do not need change
              bottom: removeWAddH, //  h+s,w-s
              left: noop,   //  anything has not change
              none: addWHFn({ wSpan: -s })  //  w-s
            },
            none: {
              top: addWHFn({ hSpan: s }), //  h+s
              right: addWHFn({ wSpan: s }), //  w+s
              bottom: addWHFn({ hSpan: s }),  //  h+s
              left: addWHFn({ wSpan: s }),  //  w+s
              none: noop   //  anything has not change
            }
          }

          console.log('azure ~~~~~')

          console.log(conditions[_oldVPos][_newVPos])
          return conditions[_oldVPos][_newVPos]
        }

        _getAddFn()()
      },

      handleTemplateBarcodeChange({ row, newV, oldV }) {
        row['barcodePos'] = newV
        // this._addWh({ grid: row, newV, oldV, barcodeHeight: this.gridBarcodeConfig.bh })

      },

      //  版上的条码更改
      handleBarcodeChange({ row, newV, oldV }) {

        // row['barcodePos'] = newV
        // this._addWh({ grid: row, newV, oldV, barcodeHeight: this.barcodeHeight })
      },

      gridStyleFn(grid) {
        if (this.multiSelectGridIds.includes(grid.key)) {
          return { opacity: .3 }
        }
      },
      generateBarcodePosStyle({ grid, barcodePos } = {}) {
        const { rotateAngle } = grid
        // console.log(barcodePos, rotateAngle)
        barcodePos = !!barcodePos ? barcodePos : directionEnum.none
        //  rotate -> angle
        const calcPosition = () => lastBarCodePos[directionEnum[barcodePos]][rotateAngle]
        const posCalcS = () => {
          const c = {
            16: 'none',
            1: 'top',
            2: 'right',
            4: 'bottom',
            8: 'left'
          }
          return c[barcodePos]
        }
        const strategies = (strategy = 1) => {
          const s = {
            1: calcPosition,
            2: posCalcS //  @deprecated error
          }
          return s[strategy]
        }
        //  先结合barcodeDirection 和 rotate angle 来算出last pos
        return generateBarcodePosStyle(strategies()())
      },
      deleteGridByKey({ gridList, grid, idx }) {
        console.log(gridList, grid, idx)
        // const k = grid['key']
        // const i = gridList.findIndex(v=>v.key === k)
        // console.log(i);
        // this.deleteGrid({$index:i,gridList })
        this.deleteGrid({ gridList, $index: idx })
      },
      deleteGrid({ $index, gridList }) {
        gridList.splice($index, 1)
      },
      rightRotateGrid({ row }) {
        const nextRotateState = function * () {
          const stack = [0, 90, 180, 270]
          while (true) {
            yield
            yield
            yield
          }
        }

        // console.log(row.rotateAngle)
        const { w, h } = row
        const c = [0, 90, 180, 270]
        const rRotateNext = angle => {
          const idx = c.findIndex(v => v === parseInt(angle, 10))
          const { length } = c
          const nextIdx = idx === length - 1 ? 0 : idx + 1
          return c[nextIdx]
        }
        row.rotateAngle = rRotateNext(row.rotateAngle)

        Object.assign(row, { w: h, h: w })
      },
      repaint() {
        this.clothKey++
        // ;(async() => {
        //   await this.$nextTick()
        //   window.dispatchEvent(new Event('resize'))
        // })()
      },
      clearGridList() {
        try {
          //  call api
          this.gridList = Array.of()
          this.repaint()
          this.$notify.success({
            title: '清空模板',
            message: '清全部模板操作成功'
          })
        } catch (e) {
          console.log(e)
        }
      },
      addGridItem() {
        const { w, h } = this.realClothWH
        const v = getUnicornKey()(this.gridList)
        // console.log(v)
        const { BoardModelID } = this.boardBaseModel
        this.gridList.push(new GridItemVO({
          // key: v, x: w, y: h * 0.2
          key: v, x: 0, y: 0, boardId: BoardModelID
        }))
      },
      async getGridItemList({ BoardModelID } = {}) {
        try {
          // const { gridList } = await import('./c/mockData')
          // const { Result,Code } = await GetBoardModelDetail({ inBoardModelId: BoardModelID })
          const { Code, Result = {} } = await GetBoardModel({
            PageSize: 1,
            PageNum: 1,
            BoardModelID
          })

          // this.rulerKey++
          if (+Code === ERR_OK) {
            const { Items: { [0]: template } = [] } = Result
            if (template) {
              const { BoardModelDetails, ...baseModel } = template
              this.boardBaseModel = {
                ...baseModel,
                [`${free_prefix}RemarkDirection`]: baseModel[`${free_prefix}RemarkDirection`],
                RemarkDirection: baseModel['RemarkDirection']
              }

              this.setOriginCloth(baseModel.Width, baseModel.Height)

              this.gridList = BoardModelDetails.map(e => {
                const {
                  X, Y, Width, Height, BoardModelDetailIId,
                  // BoardModelID,
                  PhotoIndex,
                  RotateDegrees,
                  RemarkDirection,
                  RemarkCodeSize,
                  RemarkFontSize,
                  RemarkHeight,
                  AllowRotate,
                  OriginalRemarkDirection
                } = e
                return new GridItemVO({
                  x: X, y: Y, w: Width, h: Height, key: PhotoIndex, detailId: BoardModelDetailIId,
                  rotateAngle: RotateDegrees, barcodePos: OriginalRemarkDirection
                  , name: PhotoIndex, bSize: RemarkCodeSize, bfSize: RemarkFontSize, bh: RemarkHeight,
                  allowRotate: AllowRotate, boardId: baseModel.BoardModelID
                })
              })

              //  set global barcode size
              if (Array.isArray(this.gridList) && this.gridList.length > 0) {
                const { bh, bSize, bfSize } = this.gridList.slice(0)[0]
                Object.entries({ bh, bSize, bfSize }).forEach(([k, v]) => {
                  this.gridBarcodeConfig[k] = v
                })
              }

            }
          }
          this.repaint()
        } catch (e) {
          console.log(e)
        }
      }
    },
    components: {
      MaterialSelectQuery,
      ProductPrintType,
      Sticky,
      AzureLineSelect,
      AzureDynamicTable, FullMoon, AInlineEdit, ASelect
    }
  }
</script>

<style>
  .azure-select-row {
    background: #c8dcf1 !important;
    cursor: pointer;
  }

</style>

<style lang="scss" scoped>
  /deep/ .vue-ruler-wrapper {
    overflow: unset;
  }

  .affix-form {
    /deep/ .el-form-item__content {
      vertical-align: unset;

    }
  }

</style>
